package com.cl.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.ObjectUtils;


import com.cl.entity.CcPay;

/**
 * 计算稿酬 表达式解析util
 *
 */
public class ExpressionUtil {
	
	private ScriptEngine engine;
	
	public void init()
	{
		ScriptEngineManager manager = new ScriptEngineManager();
	    this.engine = manager.getEngineByName("js");
	}
	
	/**
	 * 生成js表达式变量
	 * @param engine js引擎
	 * @param cp 计算得到的稿酬ccpay
	 * @param obj 待计算稿酬的文稿影像实体obj
	 * @throws Exception
	 */
	public void createVariable(CcPay cp, Object obj) throws Exception{
		String tn = String.valueOf(cp.getClass_());
		//0215
//		String c=ClassNameReplaceUtil.replaceName1(cp.getClass_());
//		cp.setClass_(c);
		addObjectPropToVariablesOfObj("com.cl.entity.CcPay",cp,"Cp_");
//		//0215
//		String c1=ClassNameReplaceUtil.replaceName1(cp.getClass_());
//		cp.setClass_(c1);
		addObjectPropToVariables(tn,ObjectUtils.toString(cp.getKeyval()),"",obj);
	}
	
	/**
	 * 通过类 生成js表达式变量
	 * @param engine
	 * @param cp
	 * @param objClass
	 * @param obj
	 * @throws Exception
	 */
	public void createVariable(CcPay cp, Class objClass, Object obj) throws Exception{
//		//
//		//0215
//				String c=ClassNameReplaceUtil.replaceName1(cp.getClass_());
//				cp.setClass_(c);
				
		addObjectPropToVariablesOfObj("com.cl.entity.CcPay",cp,"Cp_");
		//0215
//		String c1=ClassNameReplaceUtil.replaceName1(cp.getClass_());
//		cp.setClass_(c1);
		addObjectPropToVariables(objClass,ObjectUtils.toString(cp.getKeyval()),"",obj);
	}
	
	/**
	 * 调用addObjectPropToVariablesOfObj方法
	 * @param objType
	 * @param objVal
	 * @param engine
	 * @param preName
	 * @param obj
	 * @throws Exception
	 */
	private void addObjectPropToVariables(String objType,String objVal,String preName,Object obj) throws Exception{
		if(obj==null)throw new Exception("对象类型：["+objType+"];id:["+objVal+"]不存在;无法获取对象相关信息导致稿酬因子执行失败。");
		addObjectPropToVariablesOfObj(objType,obj,preName);
	}
	
	private void addObjectPropToVariables(Class objClass,String objVal,String preName,Object obj) throws Exception{
		if(obj==null)throw new Exception("对象类型：["+objClass+"];id:["+objVal+"]不存在;无法获取对象相关信息导致稿酬因子执行失败。");
		addObjectPropToVariablesOfObj(objClass,obj,preName);
	}
	
	/**
	 * 将对象属性赋值到js变量中
	 * @param objType 实体对象类名
	 * @param obj 文稿影像实体obj
	 * @param engine js引擎
	 * @param preName 变量前缀
	 * @throws SecurityException
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	private void addObjectPropToVariablesOfObj(String objType,Object obj,String preName) throws SecurityException, ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
		Field[] field = ClassUtils.getClass(objType).getDeclaredFields();
		
		for(int i=0;i<field.length;i++){
			//忽略serialVersionUID field
			if(field[i].getName().equalsIgnoreCase("serialVersionUID"))
				continue;
//			if(field[i].getName().equalsIgnoreCase("class_"))
//			{
//				//0215
//			String c=ClassNameReplaceUtil.replaceName1(BeanUtils.getProperty(obj, field[i].getName()));
////				cp.setClass_(c);
////				System.out.println("pppppppppppppppppppppppppppppppp02161111:"+i+field[i].getName()+BeanUtils.getProperty(obj, field[i].getName())+ c);
//				String a=BeanUtils.getProperty(obj, field[i].getName());
//				a=c;
//				
//		//		field[i].set(field[i].getName(), a);
//		//		System.out.println("pppppppppppppppppppppppppppppppp02162222:"+field[i]);
//			}
			((CcPay) obj).setClass_(ClassNameReplaceUtil.replaceName1(((CcPay) obj).getClass_()));
			engine.put(
					
				preName+field[i].getName(), BeanUtils.getProperty(obj, field[i].getName())
			);
			//System.out.println("pppppppppppppppppppppppppppppppp0216:"+ BeanUtils.getProperty(obj, field[i].getName()));
		}
		
	}
	
	
	/**
	 * 将对象属性赋值到js变量中
	 * @param objClass 实体对象类
	 * @param obj
	 * @param engine
	 * @param preName
	 * @throws SecurityException
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	private void addObjectPropToVariablesOfObj(Class objClass,Object obj,String preName) throws SecurityException, ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
		Field[] field = objClass.getDeclaredFields();

		for(int i=0;i<field.length;i++){
			//忽略serialVersionUID field
			//0215
			//obj.setClass_(ClassNameReplaceUtil.replaceName1(obj.getClass_()));
			if(field[i].getName().equalsIgnoreCase("serialVersionUID"))
				continue;
	//		((CcPay) obj).setClass_(ClassNameReplaceUtil.replaceName1(((CcPay) obj).getClass_()));
			engine.put(
				preName+field[i].getName(), BeanUtils.getProperty(obj, field[i].getName())
			);
		}
	}
	
	
	/**
	 * 执行匹配
	 * @param exp BASE_PAYFACTOR中的js表达式
	 * @param cp 计算得到的稿酬ccpay
	 * @param obj 待计算稿酬的文稿影像实体obj
	 * @return obj是否能匹配exp表达式
	 * @throws Exception
	 */
	public boolean excute(String exp,CcPay cp,Class objClass,Object obj) throws Exception{
	    
		//0214
//		cp.setClass_(ClassNameReplaceUtil.replaceName1(cp.getClass_()));
		
		createVariable(cp,objClass,obj);
		//0216
//				cp.setClass_(ClassNameReplaceUtil.replaceName1(cp.getClass_()));
				
	    Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);

	    Object result = engine.eval(exp);
		return (Boolean)result;
	}

}
